#ifndef __LOGGER_H_
#define __LOGGER_H_
#include <spdlog/spdlog.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/sinks/basic_file_sink.h>
#include <spdlog/sinks/rotating_file_sink.h>

namespace x{

	enum class LogLevel
	{
		TRACE = 0,
		DEBUG = 1,
		INFO = 2,
		WARN = 3,
		ERROR = 4,
		CRITICAL = 5
	};

	struct LoggerCfg{
		std::string name="xthread_pool";
		std::string log_path="../log/thread_pool.log";
		std::string pattern="[%y-%m-%d %H:%M:%s.%e] [%l] [%n] %v";
		LogLevel level=LogLevel::INFO;
		bool enable_console =true;
		bool enable_file =true;
		size_t max_file_size=10*1024*1024;
		size_t max_files=5;
		bool auto_flush=true;
	};

	/**
	 *单例日志管理器 
	 * 
	 * 
	 * 
	 */
	class Logger{
	public:
		static Logger& getinstance();

		bool init(const LoggerCfg& config=LoggerCfg{});

		void setlevel(LogLevel level);

		LogLevel getlevel() const;

		void flush();

		void shutdown();

		template<typename... Args>
		void Trace(const std::string &fmt,Args&&... args){
			if(logger_ && logger_->should_log(spdlog::level::trace)){
				logger_->trace(fmt,std::forward<Args>(args)...);
			}
		}

		template<typename... Args>
		void Debug(const std::string &fmt,Args&&... args){
			if(logger_ && logger_->should_log(spdlog::level::debug)){
				logger_->debug(fmt,std::forward<Args>(args)...);
			}
		}

		template<typename... Args>
		void Info(const std::string &fmt,Args&&... args){
			if(logger_ && logger_->should_log(spdlog::level::info)){
				logger_->info(fmt,std::forward<Args>(args)...);
			}
		}

		template<typename... Args>
		void Warn(const std::string &fmt,Args&&... args){
			if(logger_ && logger_->should_log(spdlog::level::warn)){
				logger_->warn(fmt,std::forward<Args>(args)...);
			}
		}

		template<typename... Args>
		void Error(const std::string &fmt,Args&&... args){
			if(logger_ && logger_->should_log(spdlog::level::error)){
				logger_->error(fmt,std::forward<Args>(args)...);
			}
		}

		template<typename... Args>
		void Critical(const std::string &fmt,Args&&... args){
			if(logger_ && logger_->should_log(spdlog::level::critical)){
				logger_->critical(fmt,std::forward<Args>(args)...);
			}
		}

		bool isinit(){return initialized_;}
	private:
		Logger()=default;
		~Logger();

		Logger(const Logger&)=delete;
		Logger& operator=(const Logger&) = delete;

		spdlog::level::level_enum tospdloglevel(LogLevel);
		bool createlogdir(const std::string& log_path);

		std::shared_ptr<spdlog::logger> logger_;
		LoggerCfg loggercfg_;
		bool initialized_=false;
	};

	
};

#define LOG_TRACE(fmt, ...)     x::Logger::getinstance().Trace(fmt, ##__VA_ARGS__)
#define LOG_DEBUG(fmt, ...)     x::Logger::getinstance().Debug(fmt, ##__VA_ARGS__)
#define LOG_INFO(fmt, ...)      x::Logger::getinstance().Info(fmt, ##__VA_ARGS__)
#define LOG_WARN(fmt, ...)      x::Logger::getinstance().Warn(fmt, ##__VA_ARGS__)
#define LOG_ERROR(fmt, ...)     x::Logger::getinstance().Error(fmt, ##__VA_ARGS__)
#define LOG_CRITICAL(fmt, ...)  x::Logger::getinstance().Critical(fmt, ##__VA_ARGS__)

// 条件日志宏
#define LOG_IF(condition, level, fmt, ...) \
    do { \
        if (condition) { \
            LOG_##level(fmt, ##__VA_ARGS__); \
        } \
    } while(0)

// 函数进入/退出跟踪宏（仅在 DEBUG 模式下有效）
#ifdef DEBUG
    #define LOG_FUNC_ENTER()    LOG_TRACE("进入函数: {}", __FUNCTION__)
    #define LOG_FUNC_EXIT()     LOG_TRACE("退出函数: {}", __FUNCTION__)
#else
    #define LOG_FUNC_ENTER()    do {} while(0)
    #define LOG_FUNC_EXIT()     do {} while(0)
#endif

// 性能测量宏
#define LOG_PERF_START(name) \
    auto __perf_start_##name = std::chrono::high_resolution_clock::now()

#define LOG_PERF_END(name) \
    do { \
        auto __perf_end = std::chrono::high_resolution_clock::now(); \
        auto __perf_duration = std::chrono::duration_cast<std::chrono::microseconds>(__perf_end - __perf_start_##name); \
        LOG_DEBUG("性能测量 [{}]: {} 微秒", #name, __perf_duration.count()); \
    } while(0)
#endif